package site.edody.dframe.ssoserver;

import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.sign.SaSignUtil;
import cn.dev33.satoken.sso.config.SaSsoServerConfig;
import cn.dev33.satoken.sso.processor.SaSsoServerProcessor;
import cn.dev33.satoken.util.SaResult;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.dtflys.forest.Forest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import org.ssssssss.magicapi.core.service.MagicAPIService;

import java.util.HashMap;
import java.util.Map;


/**
 * Sa-Token-SSO Server端使用的接口 Controller
 *
 *
 */
@RestController
public class SsoServerController {

	private final Logger log = LoggerFactory.getLogger(SsoServerController.class);

	@Autowired
	MagicAPIService service;



//	@Value("${sso.login:http://localhost:5173/#/login}")
	@NacosValue(value = "${dframe.sso.login:http://localhost:5173/#/login}", autoRefreshed = true)
	private String loginpage;
	/**
	 * SSO-Server端：处理所有SSO相关请求 
	 * 		http://{host}:{port}/sso/auth			-- 单点登录授权地址，接受参数：redirect=授权重定向地址 
	 * 		http://{host}:{port}/sso/doLogin		-- 账号密码登录接口，接受参数：name、pwd 
	 * 		http://{host}:{port}/sso/checkTicket	-- Ticket校验接口（isHttp=true时打开），接受参数：ticket=ticket码、ssoLogoutCall=单点注销回调地址 [可选] 
	 * 		http://{host}:{port}/sso/signout		-- 单点注销地址（isSlo=true时打开），接受参数：loginId=账号id、sign=参数签名
	 */
	@RequestMapping({"/sso/doLogin", "/sso/checkTicket", "/sso/signout"})
	public Object ssoRequest() {
		return SaSsoServerProcessor.instance.dister();
	}

	// SSO-Server：统一认证地址
	@RequestMapping("/sso/auth")
	public Object ssoAuth() {
		String redirect = SaHolder.getRequest().getParam("redirect");
		log.info("login from :{"+redirect+"}");
		return SaSsoServerProcessor.instance.ssoAuth();
	}

	// 配置SSO相关参数 
	@Autowired
	private void configSso(SaSsoServerConfig ssoServer) {
		log.info(ssoServer.toString());
		// 配置：未登录时返回的View 
		ssoServer.notLoginView = () -> {
			return new ModelAndView("redirect:"+loginpage);
		};
		
		// 配置：登录处理函数 
		ssoServer.doLoginHandle = (name, pwd) -> {
			// 获取验证码参数
			try{
				String code = SaHolder.getRequest().getParam("code");
				String uuid = SaHolder.getRequest().getParam("uuid");
				log.debug(SaHolder.getRequest().getSource().toString());
				log.debug("code is : "+code);
				Map<String, Object> params = new HashMap<>();
				JSONObject bodyparam = JSONUtil.createObj().set("username",name).set("password",pwd).set("code",code).set("uuid",uuid);
				params.put("body",bodyparam);
				Object value = service.execute("POST","/system/security/login",params);

				if (value instanceof String){
					return SaResult.ok("登录成功！").setData(value);
				} else {
					JSONObject returnobj = JSONUtil.parseObj(value);
					return new SaResult( Integer.parseInt(returnobj.getJSONArray("values").get(0).toString()), "error", returnobj.getJSONArray("values").get(1));
				}
			} catch (Exception e){
				log.error("登录过程异常",e);
				return  SaResult.error("登录失败！");
			}

		};
		
		// 配置 Http 请求处理器 （在模式三的单点注销功能下用到，如不需要可以注释掉） 
		ssoServer.sendHttp = url -> {
			try {
				log.info("------ 发起请求：" + url);
				String resStr = Forest.get(url).executeAsString();
				log.info("------ 请求结果：" + resStr);
				return resStr;
			} catch (Exception e) {
				e.printStackTrace();
				return null;
			}
		};
	}

	// 示例：获取数据接口（用于在模式三下，为 client 端开放拉取数据的接口）
	@RequestMapping("/sso/getData")
	public SaResult getData(String apiType, String loginId) {
		log.info("---------------- 获取数据 ----------------");
		log.info("apiType=" + apiType);
		log.info("loginId=" + loginId);

		// 校验签名：只有拥有正确秘钥发起的请求才能通过校验
		SaSignUtil.checkRequest(SaHolder.getRequest());

		// 自定义返回结果（模拟）
		return SaResult.ok()
				.set("id", loginId)
				.set("name", "LinXiaoYu")
				.set("sex", "女")
				.set("age", 18);
	}






}
